#pragma once

#include "Engine.h"
#include "Defines.h"
#include "ModuleScheduler.h"

class ModuleScheduler;

class Module
{
public:
	friend class Engine;
	friend class ModuleScheduler;

	Module(void): m_dead(false),m_running(false),m_loaded(false),
				  m_scheduler(NULL),m_window(NULL) {}
	virtual ~Module(void) {}

	inline bool IsRunning() const { return m_running; }
	inline void Stop() { m_running = true; }
	inline void Start() { m_running = true; }
	inline bool IsAlive() const { return !m_dead; }
	inline void Kill() { m_dead = true; }
	inline void Revive() { m_dead = false; }

private:
	virtual void SetWindow(sf::RenderWindow* window) { m_window = window; }
	void DispatchEvent(const sf::Event& e);	//dispatches the events

protected:
	virtual void OnOpen() { m_loaded ?  m_running = true : m_running = false; }
	virtual void OnLoad() { m_loaded = true;}
	virtual void OnLoop(float diff) {}
	virtual void OnFrame(float diff) {}
	virtual void OnClose() { m_running = false; }
	virtual void OnUnload() {}

	/* events */
	virtual void OnKeyPressed(const sf::Event& e) {}
	virtual void OnKeyReleased(const sf::Event& e) {}
	virtual void OnMousePressed(const sf::Event& e) {}
	virtual void OnMouseReleased(const sf::Event& e){}

	virtual void OnResize(const sf::Event& e) {}
	virtual void OnOtherEvent(const sf::Event& e) {}

	bool m_dead;
	bool m_running;
	bool m_loaded;
	sf::RenderWindow* m_window;
	ModuleScheduler* m_scheduler;			//pointer to the next module if any
};
